/**
 * @author: 子龙
 */
package com.fzl.lotterysystem.service.activitystatus.impl;

import com.fzl.lotterysystem.common.errorcode.ServiceErrorCodeConstants;
import com.fzl.lotterysystem.common.exception.ServiceException;
import com.fzl.lotterysystem.service.ActivityService;
import com.fzl.lotterysystem.service.DTO.ConvertActivityStatusDTO;
import com.fzl.lotterysystem.service.activitystatus.ActivityStatusManager;
import com.fzl.lotterysystem.service.activitystatus.operator.AbstractActivityOperator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Slf4j
@Component
@Transactional(rollbackFor = Exception.class)
public class ActivityStatusManagerImpl implements ActivityStatusManager {


    //map：包含所有参数  map<String , AbstractActivityOperator>
    @Autowired
    private final Map<String, AbstractActivityOperator> operatorMap = new HashMap<>();

    @Autowired
    private ActivityService activityService;


    /**
     * 扭转状态
     * @param convertActivityStatusDTO
     */
    @Override
    public void handlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {


        if(CollectionUtils.isEmpty(operatorMap)){
            log.warn("operatorMap为空");
            return;
        }

        Map<String, AbstractActivityOperator> currMap = new HashMap<>(operatorMap);
        Boolean update = false;
        //先处理人员奖品
        update = processConvertStatus(convertActivityStatusDTO,currMap,1);

        //后处理活动
        update = processConvertStatus(convertActivityStatusDTO,currMap,2)|| update;

        //更新缓存
        if (update) {
            activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
        }
    }

    /**
     * 回滚状态
     * @param convertActivityStatusDTO
     */
    @Override
    public void rollBackHandlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        //operatorMap：活动人员奖品
        //活动是否需要回滚：绝对需要，因为奖品回滚成INIT，那么该活动就有为抽完的奖品
        //没有顺序，都回滚
        for(AbstractActivityOperator operator : operatorMap.values()){
            operator.convert(convertActivityStatusDTO);
        }
        //缓存更新
        activityService.cacheActivity(convertActivityStatusDTO.getActivityId());

    }

    /**
     * 扭转状态
     * @param convertActivityStatusDTO
     * @param currMap
     * @param sequence
     * @return
     */
    private Boolean processConvertStatus(ConvertActivityStatusDTO convertActivityStatusDTO,
                                         Map<String, AbstractActivityOperator> currMap,
                                         int sequence) {
        Boolean update = false;

        //遍历currMap
        Iterator<Map.Entry<String,AbstractActivityOperator>> iterator= currMap.entrySet().iterator();
        while (iterator.hasNext()) {
            AbstractActivityOperator operator= iterator.next().getValue();
            //operator是否转换
            if(operator.sequence()!=sequence
                                           || ! operator.needConvert(convertActivityStatusDTO)){
                continue;
            }
            //转换
            if(!operator.convert(convertActivityStatusDTO)){
                log.error("{}转换失败",operator.getClass().getName());
                throw new ServiceException(ServiceErrorCodeConstants.ACTIVITY_STATUS_CONVERT_ERROR);
            }

            //currMap删除当前operator
            iterator.remove();

            //转换成功，update为true
            update = true;
        }


        //返回
        return update;
    }
}